#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>

//#include "types.h"
#include "sys_main.h"

char sys_trace_data_file_name[FILENAME_MAX];
double sys_clock_rate;
FILE* sys_trace_data_file_in;

char line_buffer[MAX_LINE_LEN];
int  line_number=0;
char *tokens[MAX_TOKEN];

//
//  convert the tsc time to ms, it is important to know the clock rate in advance!
//  return values: the converted value (in millisec)
//
double convert_tsc_to_ms( unsigned long long tsc_time )
{
    double res;
    res = (double)(tsc_time)/(double)(sys_clock_rate*1000);
    return res;
}

//
//  convert a period of time (in seconds) to TSC value, according to the CPU frequency.
//  return values: the time expressed in TSC value
//
unsigned long long convert_ms_to_tsc( double ms )
{
    unsigned long long res;
    res = (unsigned long long)(ms*(double)(sys_clock_rate*1000));
    return res;
}

//
// Init clock rate form .vsa_tsc or /proc/cpuinfo
//
void init_clock_rate( void )
{
  FILE *fp = NULL;
  char *buf = NULL;
  char token[] = "cpu MHz";
  char *pos;
  size_t len = 0;
  size_t i = 0;
  sys_clock_rate = 0;

  /* test if file .vsa_tsc exist */
  fp = fopen(".vsa_tsc", "r");
  if (fp != NULL) {
    /* file exist */
    i = getline(&buf, &len, fp);
    if (buf != NULL) {
      sys_clock_rate = atof(buf);
      free(buf);
      buf = NULL;
    }
    fclose(fp);
  }

  if (sys_clock_rate <= 0) {
    /* fall back to get sys_clock_rate from /proc/cpuinfo */
    fp = fopen("/proc/cpuinfo", "r");
    if (fp == NULL) {
      sys_clock_rate = DUMMY_CLOCK_RATE;
    } else {
      sys_clock_rate = 0;
      /* parse file */
      while (((getline(&buf, &len, fp)) != -1) && (sys_clock_rate == 0)) {
        if (buf != NULL) {
          pos = strstr(buf, token);
          if (pos != NULL) {
            pos = strstr(buf, ":");
            if (pos != NULL) {
              sys_clock_rate = atof(pos+1);
            }
          }
          free(buf);
          buf = NULL;
        }
      }
      fclose(fp);
    }
  }

  if (sys_clock_rate <= 0) {
    sys_clock_rate = DUMMY_CLOCK_RATE;
  }

  return;
}

//
// update clock rate file .vsa_tsc
//
void update_clock_rate( void )
{
  FILE *fp;

  fp = fopen(".vsa_tsc", "w");
  if (fp != NULL) {
    fprintf(fp, "%f\n", sys_clock_rate);
    fclose(fp);
  }

  return;
}

//
// pause and wait for user, any key to continue
//
void pause_any_key( void )
{
    char buf[20];
    char *res;

    printf("Press Enter to continue:");
    res=fgets(buf, 20, stdin);
}

//
//  the following routine is used to set (confirm) the initial system variables
//  such as Number of PCPU, the System Clock rate and the input file name
//  return value: -1 means the input file does not exist; 0 means successful
//
int sys_init( void )
{
    char input[20], temp_file_name[FILENAME_MAX];
    char *res;

//----------------------------------    Setting default values for the initial parameters   ----------------------
    sys_clock_rate = 0;
    sprintf( sys_trace_data_file_name, "%s", "rec-sample.txt" );
//----------------------------------    Setting default values for the initial parameters   ----------------------

    input[0] = '\0';
    init_clock_rate( );
    printf( "The clock rate of the system is [%8.3f]", sys_clock_rate );
    res = fgets( input, 20, stdin );
//    printf( "input=%s; after conversion:%8.3f\n", input, atof(input) );

    if( atof( input ) < 0.0 ){
        printf( "The clock rate can not be negative, it remains %8.3f hereafterin\n", sys_clock_rate );
    }else if( atof( input ) > 0.0 ){
        sys_clock_rate=atof(input);
        update_clock_rate( );
    }

    printf( "The input text trace file name is [%s]", sys_trace_data_file_name );
    res = fgets( temp_file_name, FILENAME_MAX, stdin );
    //since the obtained line contains one character '\n', we should get rid of it before processing
    temp_file_name[strlen(temp_file_name)-1] = '\0';
    if( strlen( temp_file_name ) > 0 ) strcpy( sys_trace_data_file_name, temp_file_name );

    //open the input file now.
    if ( (sys_trace_data_file_in = fopen( sys_trace_data_file_name, "r" )) == NULL ){
        printf( "can not open the input file!\n" );
        return -1;
    }

    printf( "------------------\tConfirmation information\t---------------\n" );
    printf( "Clock rate:%8.3f\n", sys_clock_rate );
    printf( "Input file name:%s\n", sys_trace_data_file_name );
    printf( "------------------\tConfirmation information\t---------------\n" );
	pause_any_key( );
    return 0;
}

//
// sys_exit: quit the system now
//
void sys_exit( void )
{
	fclose( sys_trace_data_file_in );
	printf( "Resouces used in the SYSTEM module are reclaimed.\n" );
}

//
// read_line: Read one line from rec.txt, and parse it into tokens.
// The line will be stored in line_buffer
//
int read_line( void )
{
	int i;
	char* res;

	if(( res = fgets( line_buffer, MAX_LINE_LEN, sys_trace_data_file_in )) == NULL )
		return TRACE_FILE_EOF;

	line_number ++;

	//parse the line buffer now
    for( i=0; i<MAX_TOKEN ; i++ ){
		if( i==0 )
			tokens[i] = strtok( line_buffer, " (+)[]=," );
        else
            tokens[i] = strtok( NULL, " (+)[]=," );

        if( tokens[i] == NULL ) break;
    }   
    if( (i>=MAX_TOKEN) && (i<3) ) return -1; //sanity check
	
	return 0;
}

